/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including but not limited to the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to provide persons with access to the Software
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGE OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/* eslint-disable @typescript-eslint/no-inferrable-types */
export class MusicPlayer {
  private playlist: string[];
  private currentTrackIndex: number;
  private isPlaying: boolean;
  private volume: number;
  private audioElement: HTMLAudioElement;
  private playbackRate: number;
  private isShuffle: boolean;
  private isRepeat: boolean;
  private originalPlaylist: string[]; // 用于保存原始播放列表（随机播放时使用）
  private currentTime: number = 0;
  private duration: number = 0;
  private timeUpdateCallbacks: Array<(currentTime: number, duration: number) => void> = [];

  constructor(initialPlaylist: string[] = []) {
    this.playlist = [...initialPlaylist];
    this.originalPlaylist = [...initialPlaylist];
    this.currentTrackIndex = 0;
    this.isPlaying = false;
    this.volume = 0.7; // 默认音量70%
    this.playbackRate = 1.0; // 默认播放速度
    this.isShuffle = false;
    this.isRepeat = false;

    // 创建音频元素
    this.audioElement = new Audio();
    this.audioElement.volume = this.volume;
    this.audioElement.playbackRate = this.playbackRate;
    if (this.playlist[this.currentTrackIndex]) {
      this.audioElement.src = this.playlist[this.currentTrackIndex];
    }

    // 设置事件监听
    this.setupEventListeners();
  }

  /**
   * 设置事件监听
   */
  private setupEventListeners(): void {
    this.audioElement.addEventListener("ended", () => this.handleTrackEnd());
    this.audioElement.addEventListener("error", (e) => this.handleError(e));
    this.audioElement.addEventListener("timeupdate", () =>
      this.handleTimeUpdate()
    );
  }

  /**
   * 处理播放结束事件
   */
  private handleTrackEnd(): void {
    if (this.isRepeat) {
      this.playCurrentTrack();
    } else {
      this.next();
    }
  }

  /**
   * 处理错误事件
   */
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  private handleError(event: Event): void {
    console.error("播放错误:", this.audioElement.error);
    this.next(); // 出错时自动播放下一首
  }

  /**
   * 处理时间更新事件（可用于UI更新）
   */
  private handleTimeUpdate(): void {
    this.currentTime = this.audioElement.currentTime;
    this.duration = this.audioElement.duration || 0;
    // 通知所有回调函数
    this.timeUpdateCallbacks.forEach(cb => cb(this.currentTime, this.duration));
  }

  /**
   * 播放当前曲目
   */
  private playCurrentTrack(): void {
    if (this.playlist.length === 0) {
      console.warn("播放列表为空");
      return;
    }
    this.audioElement.src = this.playlist[this.currentTrackIndex];
    console.log(this.audioElement.src);
    this.audioElement
      .play()
      .then(() => {
        this.isPlaying = true;
      })
      .catch((error) => {
        console.error("播放失败:", error);
        this.isPlaying = false;
      });
  }

  /**
   * 播放音乐
   */
  public play(): void {
    if (!this.isPlaying) {
      console.log(this.audioElement.src);
      if (this.audioElement.src) {
        this.audioElement
          .play()
          .then(() => {
            this.isPlaying = true;
          })
          .catch((error) => {
            console.error("播放失败:", error);
          });
      } else {
        this.playCurrentTrack();
      }
    }
  }

  /**
   * 暂停音乐
   */
  public pause(): void {
    if (this.isPlaying) {
      this.audioElement.pause();
      this.isPlaying = false;
    }
  }

  /**
   * 切换播放/暂停状态
   */
  public togglePlay(): void {
    if (this.isPlaying) {
      this.pause();
    } else {
      this.play();
    }
  }

  /**
   * 播放下一首
   */
  public next(): void {
    if (this.playlist.length === 0) return;

    this.currentTrackIndex =
      (this.currentTrackIndex + 1) % this.playlist.length;
    this.playCurrentTrack();
  }

  /**
   * 播放上一首
   */
  public prev(): void {
    if (this.playlist.length === 0) return;

    this.currentTrackIndex =
      (this.currentTrackIndex - 1 + this.playlist.length) %
      this.playlist.length;
    this.playCurrentTrack();
  }

  /**
   * 设置音量 (0-1)
   */
  public setVolume(volume: number): void {
    const validatedVolume = Math.max(0, Math.min(1, volume));
    this.volume = validatedVolume;
    this.audioElement.volume = validatedVolume;
  }

  /**
   * 获取当前音量
   */
  public getVolume(): number {
    return this.volume;
  }

  /**
   * 设置播放速度 (0.5-4)
   */
  public setPlaybackRate(rate: number): void {
    const validatedRate = Math.max(0.5, Math.min(4, rate));
    this.playbackRate = validatedRate;
    this.audioElement.playbackRate = validatedRate;
  }

  /**
   * 获取当前播放速度
   */
  public getPlaybackRate(): number {
    return this.playbackRate;
  }

  /**
   * 切换随机播放
   */
  public toggleShuffle(): void {
    this.isShuffle = !this.isShuffle;

    if (this.isShuffle) {
      // 保存原始播放列表
      this.originalPlaylist = [...this.playlist];

      // 创建洗牌后的播放列表
      const shuffled = [...this.playlist];
      for (let i = shuffled.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
      }

      // 保持当前播放的歌曲在新列表中的位置
      const currentTrack = this.playlist[this.currentTrackIndex];
      const newIndex = shuffled.indexOf(currentTrack);
      [shuffled[0], shuffled[newIndex]] = [shuffled[newIndex], shuffled[0]];

      this.playlist = shuffled;
      this.currentTrackIndex = 0;
    } else {
      // 恢复原始播放列表
      const currentTrack = this.playlist[this.currentTrackIndex];
      this.playlist = [...this.originalPlaylist];
      this.currentTrackIndex = this.playlist.indexOf(currentTrack);
      if (this.currentTrackIndex === -1) this.currentTrackIndex = 0;
    }
  }

  /**
   * 切换循环播放
   */
  public toggleRepeat(): void {
    this.isRepeat = !this.isRepeat;
  }

  /**
   * 添加歌曲到播放列表
  */
  public addToPlaylist(track: string): void {
    this.playlist.push(track);
    if (!this.isShuffle) {
      this.originalPlaylist.push(track);
    }
  }

  /**
   * 从播放列表移除歌曲
   */
  public removeFromPlaylist(index: number): void {
    if (index < 0 || index >= this.playlist.length) return;

    // 如果删除的是当前播放的歌曲或之前的歌曲，需要调整当前索引
    if (index < this.currentTrackIndex) {
      this.currentTrackIndex--;
    } else if (index === this.currentTrackIndex) {
      // 如果删除的是当前播放的歌曲，停止播放
      this.pause();
      this.audioElement.src = '';
      this.currentTrackIndex = Math.min(this.currentTrackIndex, this.playlist.length - 2);
    }

    this.playlist.splice(index, 1);
    if (!this.isShuffle) {
      this.originalPlaylist.splice(index, 1);
    }
  }

  /**
   * 获取当前播放状态
   */
  public getPlaybackStatus(): {
    isPlaying: boolean;
    currentTrack: string;
    currentTrackIndex: number;
    playlist: string[];
    volume: number;
    playbackRate: number;
    isShuffle: boolean;
    isRepeat: boolean;
  } {
    return {
      isPlaying: this.isPlaying,
      currentTrack: this.playlist[this.currentTrackIndex] || '',
      currentTrackIndex: this.currentTrackIndex,
      playlist: [...this.playlist],
      volume: this.volume,
      playbackRate: this.playbackRate,
      isShuffle: this.isShuffle,
      isRepeat: this.isRepeat,
    };
  }

  /**
   * 跳转到指定时间
   */
  public seekTo(time: number): void {
    if (!isNaN(time) && this.audioElement.duration) {
      console.log(time);
      this.audioElement.currentTime = Math.max(0, Math.min(time, this.audioElement.duration));
    }
  }

  /**
   * 获取当前播放时间
   */
  public getCurrentTime(): number {
    console.log(this.audioElement.currentTime);
    return this.audioElement.currentTime;
  }

  /**
   * 获取歌曲总时长
   */
  public getDuration(): number {
    console.log(this.audioElement.duration);
    return this.audioElement.duration || 0;
  }

  // 添加时间更新订阅方法
  public onTimeUpdate(callback: (currentTime: number, duration: number) => void): void {
    this.timeUpdateCallbacks.push(callback);
  }

  // 移除时间更新订阅
  public offTimeUpdate(callback: (currentTime: number, duration: number) => void): void {
    this.timeUpdateCallbacks = this.timeUpdateCallbacks.filter(cb => cb !== callback);
  }

  /**
   * 清理资源
   */
  public dispose(): void {
    this.pause();
    this.audioElement.removeEventListener('ended', () => this.handleTrackEnd());
    this.audioElement.removeEventListener('error', (e) => this.handleError(e));
    this.audioElement.removeEventListener('timeupdate', () => this.handleTimeUpdate());
    this.audioElement.src = '';
  }
}

